In [399]:
import numpy as np
from numba import autojit
In [400]:
size = (4,4)
In [401]:
A = np.random.randint(0,2,size)
print A
In [402]:
ng = (2, 2)
gridl = [s/n for s,n in zip(size,ng)]
print gridl
In [403]:
gs = [[l * i for i in range(ngi)] for ngi,l in zip(ng,gridl)]
print gs
In [404]:
import itertools
In [405]:
gs = list(itertools.product(*gs))
print gs
In [406]:
slices = [[(slice(i,i+l)) for i, l in zip(gsi,gridl)] for gsi in gs]
sliceA = [slice(0,s) for s in size]
print slices
print sliceA
In [407]:
slicei = slices[0]
print slicei
In [408]:
grids = [A[i] for i in slices]
In [409]:
print A
print sliceA
for grid, slice in zip(grids,slices):
print grid
print slice
In [410]:
def hashfun(g, s):
"""Given a grid and a slice defining its range, compute hash using a hash function that can be reduced over subgrids by summation """
X = np.mgrid[s]
h = 0
for i in range(X.shape[0]):
h += np.sum((X[i] + 1)*g)
return h
In [411]:
hashes = [hashfun(g, s) for g, s in zip(grids, slices)]
print sum(hashes)
print hashfun(A, sliceA)
In [412]:
X = np.mgrid[s]
print X.shape
In [413]:
ranges = [np.arange(s.start, s.stop) for s in slicei]
print ranges
In [414]:
@autojit
def life_step(g, gnew):
"""Given a grid, compute one Game of Life step along the interior of the grid into gnew"""
m,n = g.shape
for i in range(1,m-1):
for j in range(1,n-1):
sum = 0
for ii in range(i-1,i+2):
for jj in range(j-1,j+2):
if ii == i and jj == j:
continue
sum += g[ii,jj]
if sum < 2 or sum > 3:
gnew[i,j] = 0
elif sum == 3:
gnew[i,j] = 1
else:
gnew[i,j] = g[i,j]
In [415]:
#A = np.ones(size, dtype=np.int64)
A = np.random.randint(0,2,size)
print A
In [416]:
B = np.zeros_like(A)
In [417]:
life_step(A, B)
In [418]:
print B
In [419]:
import numpy.testing as npt
size = (4,4)
glide_size = (16,16)
def test_ones():
"""check that all ones gives right result"""
A = np.ones(size, dtype=np.int64)
B = np.zeros_like(A)
life_step(A,B)
npt.assert_equal(A, np.ones(size))
npt.assert_equal(B, np.zeros(size))
def test_zeros():
"""check that all zeros gives right result"""
A = np.zeros(size, dtype=np.int64)
B = np.zeros_like(A)
life_step(A,B)
npt.assert_equal(A, np.zeros(size))
npt.assert_equal(B, np.zeros(size))
def test_block():
"""check that an internal block gives the right result"""
A = np.zeros(size, dtype=np.int64)
A[1:2][1:2] = 1
B = np.zeros_like(A)
C = A.copy()
life_step(A,B)
npt.assert_equal(A, B)
npt.assert_equal(A, C)
def test_two_blocks():
"""check that an internal block is correctly preserved"""
A = np.zeros(size, dtype=np.int64)
A[1:2][1:2] = 1
B = np.zeros_like(A)
C = A.copy()
life_step(A,B)
life_step(B,A)
npt.assert_equal(A, B)
npt.assert_equal(A, C)
def test_glider():
"""check that a glider moves correctly"""
G = np.zeros((3,3), dtype=np.int64)
G[0,1] = 1
G[1,2] = 1
G[2,0:3] = 1
A = np.zeros(glide_size, dtype=np.int64)
B = np.zeros_like(A)
A[1:4,1:4] = G
life_step(A,B)
C = np.zeros_like(A)
C[2][[1,3]] = 1
C[3,2:4] = 1
C[4,2] = 1
npt.assert_equal(B, C)
In [420]:
test_ones()
test_zeros()
test_block()
test_two_blocks()
test_glider()
In [421]:
G = np.zeros((3,3), dtype=np.int64)
G[0,1] = 1
G[1,2] = 1
G[2,0:3] = 1
print G
A = np.zeros((5,5), dtype=np.int64)
A[1:4,1:4] = G
print A